
package yyy.ab.common.utils;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 *
 */
public class DateUtils {

	public static final int FIRST_DAY_OF_WEEK = Calendar.MONDAY; // 中国周一是一周的第一天

	public static final int HOUR_OF_DAY = 24;
	public static final int MINUTE_OF_HOUR = 60;
	public static final int SECOND_OF_MINUTE = 60;
	public static final int MILLISECOND_OF_SECOND = 1000;

	public static final String CHINA_FORMAT = "yyyy年MM月dd日";

	/**
	 * 年月日时分秒毫秒(无下划线) yyyyMMddHHmmssSSS
	 */
	public static final String DT_LONG_FULL = "yyyyMMddHHmmssSSS";

	/**
	 * 年月日时分秒(无下划线) yyyyMMddHHmmss
	 */
	public static final String DT_LONG = "yyyyMMddHHmmss";

	/**
	 * 完整时间 yyyy-MM-dd HH:mm:ss
	 */
	public static final String SIMPLE = "yyyy-MM-dd HH:mm:ss";

	/**
	 * 年月日(无下划线) yyyyMMdd
	 */
	public static final String DT_SHORT = "yyyyMMdd";
	/**
	 * 年月日(无下划线) yyyyMMdd
	 */
	public static final String DT_MONTH = "yyyyMM";

    /**
     * 年月日带中划线
     */
    public static final String SIMPLE_UNDERLINE_DAY = "yyyy-MM-dd";

    /**
     * 获取当前时间
     *
     * @return 时间
     */
    public static Date now() {
        return Date.from(Instant.now());
    }

    /**
     * 返回yyyy-MM-dd hh:mm:ss格式时间
     *
     * @param strDate 时间字符串
     * @return yyyy-MM-dd hh:mm:ss格式时间
     */
    public static Date parseDate(String strDate) {
        return parseDate(strDate, null);
    }

    /**
     * parseDate
     *
     * @param strDate 时间字符串
     * @param pattern 格式
     * @return 时间
     */
    public static Date parseDate(String strDate, String pattern) {
        if (pattern == null) {
            pattern = DT_LONG;
        }

        if (pattern.equals(SIMPLE_UNDERLINE_DAY)) {
            pattern = SIMPLE;
            strDate += " 00:00:00";
        }
        LocalDateTime localDateTime = LocalDateTime.parse(strDate, DateTimeFormatter.ofPattern(pattern));
        Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();

		return Date.from(instant);
	}

	/**
	 * format date
	 *
	 * @param date 时间
	 * @return yyyy-MM-dd hh:mm:ss字符串
	 */
	public static String formatDate(Date date) {
		return formatDate(date, null);
	}

	/**
	 * format date
	 *
	 * @param date 时间
	 * @param pattern 格式
	 * @return 时间字符串
	 */
	public static String formatDate(Date date, String pattern) {
		if (pattern == null) {
			pattern = DT_LONG;
		}

		return DateTimeFormatter.ofPattern(pattern).format(LocalDateTime.ofInstant(date.toInstant(), ZoneId.of("Asia/Shanghai")));
	}

	private static LocalDateTime getLocalDateTime(Date date) {
		Instant timestamp = date.toInstant();
		return LocalDateTime.ofInstant(timestamp, ZoneId.of("Asia/Shanghai"));
	}


	/**
	 * 获取年份
	 * @return 年份
	 */
	public static int getYear() {
		LocalDateTime currentTime = LocalDateTime.now();
		return currentTime.getYear();
	}

	/**
	 * 取得日期：年
	 *
	 * @param date 时间
	 * @return 年
	 */
	public static int getYear(Date date) {
		return getLocalDateTime(date).getYear();
	}

	/**
	 * 获取月份
	 * @return 月份
	 */
	public static int getMonth() {
		LocalDateTime currentTime = LocalDateTime.now();
		return currentTime.getMonthValue();
	}

	/**
	 * 取得日期：月
	 *
	 * @param date 时间
	 * @return 月
	 */
	public static int getMonth(Date date) {
		return getLocalDateTime(date).getMonthValue();
	}

	public static int getDay() {
		LocalDateTime currentTime = LocalDateTime.now();
		return currentTime.getDayOfMonth();
	}

	/**
	 * 取得日期：年
	 *
	 * @param date 时间
	 * @return 日
	 */
	public static int getDay(Date date) {
		return getLocalDateTime(date).getDayOfMonth();
	}

	/**
	 * 取得月第一天
	 *
	 * @param date
	 * @return
	 */
	public static Date getFirstDateOfMonth(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.DAY_OF_MONTH, c.getActualMinimum(Calendar.DAY_OF_MONTH));
		return c.getTime();
	}

	/**
	 * 取得月最后一天
	 *
	 * @param date 时间
	 * @return 每月最后一天
	 */
	public static Date getLastDateOfMonth(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
		return c.getTime();
	}

	/**
	 * 取得周期第一天
	 *
	 * @param date 时间
	 * @return 每季度第一天
	 */
	public static Date getFirstDateOfSeason(Date date) {
		return getFirstDateOfMonth(getSeasonDate(date)[0]);
	}

	/**
	 * 取得周期最后一天
	 *
	 * @param date 时间
	 * @return 每季度最好一天
	 */
	public static Date getLastDateOfSeason(Date date) {
		return getLastDateOfMonth(getSeasonDate(date)[1]);
	}
	public static Date getBeforeOfDate(Date date){

		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date());//设置当前日期
		calendar.add(Calendar.MONTH, -2);//月份减2
		return calendar.getTime();
	}


	/**
	 * 取得周期月
	 *
	 * @param date 时间
	 * @return 周期月数组
	 */
	public static Date[] getSeasonDate(Date date) {
		Date[] season = new Date[2];

		Calendar c = Calendar.getInstance();
		c.setTime(date);

		int nSeason = getSeason(date);
		if (nSeason == 1) {// 第一个周期
			c.set(Calendar.MONTH, Calendar.JANUARY);
			season[0] = c.getTime();
			c.set(Calendar.MONTH, Calendar.FEBRUARY);
			season[1] = c.getTime();

		} else if (nSeason == 2) {// 第二个周期
			c.set(Calendar.MONTH, Calendar.MARCH);
			season[0] = c.getTime();
			c.set(Calendar.MONTH, Calendar.APRIL);
			season[1] = c.getTime();

		} else if (nSeason == 3) {// 第三个周期
			c.set(Calendar.MONTH, Calendar.MAY);
			season[0] = c.getTime();
			c.set(Calendar.MONTH, Calendar.JUNE);
			season[1] = c.getTime();



		} else if (nSeason == 4) {// 第四个周期

			c.set(Calendar.MONTH, Calendar.JULY);
			season[0] = c.getTime();
			c.set(Calendar.MONTH, Calendar.AUGUST);
			season[1] = c.getTime();

		}else if (nSeason == 5) {// 第五个周期
			season[0] = c.getTime();
			c.set(Calendar.MONTH, Calendar.SEPTEMBER);
			season[1] = c.getTime();
			c.set(Calendar.MONTH, Calendar.OCTOBER);

		}else if (nSeason == 6) {// 第六个周期
			c.set(Calendar.MONTH, Calendar.NOVEMBER);
			season[0] = c.getTime();
			c.set(Calendar.MONTH, Calendar.DECEMBER);
			season[1] = c.getTime();

		}
		return season;
	}


	/**
	 * 按2个月为一个周期
	 * 1-6 第1-6个周期
	 *
	 * @param date 时间
	 * @return 第几个周期
	 */
	public static int getSeason(Date date) {

		int season = 0;

		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int month = c.get(Calendar.MONTH);
		switch (month) {
			case Calendar.JANUARY:
			case Calendar.FEBRUARY:

				season = 1;
				break;
			case Calendar.MARCH:
			case Calendar.APRIL:

				season = 2;
				break;
			case Calendar.MAY:
			case Calendar.JUNE:

				season = 3;
				break;
			case Calendar.JULY:
			case Calendar.AUGUST:

				season = 4;
				break;
			case Calendar.SEPTEMBER:
			case Calendar.OCTOBER:

				season = 5;
				break;
			case Calendar.NOVEMBER:
			case Calendar.DECEMBER:
				season = 6;
				break;

			default:
				break;
		}
		return season;
	}

	/**
	 * 获取今天日期
	 * @return 日期
	 */
	public static Date getDateOfToday() {
		return getDate();
	}

	/**
	 * 获取今天午夜时间
	 * @return 午夜时间
	 */
	public static Date getMidnightOfToday() {
		Calendar c = Calendar.getInstance();
		c.set(Calendar.HOUR_OF_DAY, 23);
		c.set(Calendar.MINUTE, 59);
		c.set(Calendar.SECOND, 59);
		return c.getTime();
	}

	/**
	 * 获取昨天的时间
	 * @return 昨天
	 */
	public static Date yesterday() {
		Date yesterday = new Date(System.currentTimeMillis() - 24 * 3600  * 1000);
		return yesterday;
	}

	/**
	 * 获取时间的日期
	 * @param date 时间
	 * @return 日期
	 */
	public static Date getDate(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.HOUR_OF_DAY, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);
		c.set(Calendar.MILLISECOND, 0);
		return c.getTime();
	}

	/**
	 * 获取某个时间的午夜
	 * @param date 时间
	 * @return 午夜
	 */
	public static Date getMidnight(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.HOUR_OF_DAY, 23);
		c.set(Calendar.MINUTE, 59);
		c.set(Calendar.SECOND, 59);
		return c.getTime();
	}

	/**
	 * 在时间上增加天数
	 * @param time 时间
	 * @param num 天
	 * @return 时间
	 */
	public static Date addDate(Date time, int num) {
		Calendar c = Calendar.getInstance();
		c.setTime(time);
		c.add(Calendar.DATE, num);
		return c.getTime();
	}

	/**
	 * 读取excel时间数字转换为date类型
	 * @param dateNum excel时间对于的数字
	 * @return 时间
	 */
	public static Date excelDate(int dateNum) {
        Calendar calendar = new GregorianCalendar(1900, 0, -1);
        Date d = calendar.getTime();
        return addDate(d, dateNum);
    }

    /**
     * 将excel 中的日期格式转换为日期格式
     * @param dateString 时间字符串
     * @return 日期
     */
    public static Date excelDate(String dateString) {
        String dateNumEx = "\\d{4,5}";
        Pattern compile = Pattern.compile(dateNumEx);
        Matcher matcher = compile.matcher(dateString);
        if (matcher.matches()) {
            return DateUtils.excelDate(Integer.valueOf(dateString));
        }
        String dateStrEx = "(\\d{4}/\\d{1,2}/\\d{1,2})";
        compile = Pattern.compile(dateStrEx);
        Matcher matcher2 = compile.matcher(dateString);
        if (matcher2.matches()) {
            return DateUtils.parseDate(dateString, "yyyy/MM/dd");
        }

        String dateStrEx2 = "(\\d{4}.\\d{1,2}.\\d{1,2})";
        compile = Pattern.compile(dateStrEx2);
        Matcher matcher3 = compile.matcher(dateString);
        if (matcher3.matches()) {
            String replace = dateString.replace(".", "/");
            return DateUtils.parseDate(replace, "yyyy/MM/dd");
        }

        String dateStrEx3 = "(\\d{4}-\\d{1,2}-\\d{1,2})";
        compile = Pattern.compile(dateStrEx3);
        Matcher matcher4 = compile.matcher(dateString);
        if (matcher4.matches()) {
            String replace = dateString.replace("-", "/");
            return DateUtils.parseDate(replace, "yyyy/MM/dd");
        }
        return null;
    }

    /**
     * @param dateString Thu May 18 2017 00:00:00 GMT+0800 (中国标准时间)
     * @return 年月日;
     */
    public static Date parseGMTTime(String dateString) {
		dateString = dateString.replace("GMT", "").replaceAll("\\(.*\\)", "");
//        将字符串转化为date类型，格式2016-10-12
//		String logline  = "2016-12-21 20:50:25 Wednesday December +0000";
//		String format  = "yyyy'-'MM'-'dd' 'HH':'mm':'ss' 'EEEE' 'MMMM' 'ZZ";
		String format  = "EEE MMM dd yyyy HH:mm:ss ZZ";
		ZonedDateTime localDateTime = DateTimeFormatter.ofPattern(format).withLocale(Locale.ENGLISH).parse(dateString, ZonedDateTime::from);
		localDateTime.toInstant();

        return Date.from(localDateTime.toInstant());

    }
	/**
	 * 在指定日期上增加或减少天数 *
	 */
	public static Date addDay(Date date, int num) {
		Calendar startDT = Calendar.getInstance();
		startDT.setTime(date);
		startDT.add(Calendar.DAY_OF_MONTH, num);
		return startDT.getTime();
	}

	/**
	 * 在指定日期上增加或减少月数 *
	 */
	public static Date addMonth(Date date, int month) {
		Calendar startDT = Calendar.getInstance();
		startDT.setTime(date);
		startDT.add(Calendar.MONTH, month);
		return startDT.getTime();
	}

	/**
	 * 在指定日期上增加或减少年数 *
	 */
	public static Date addYear(Date date, int year) {
		Calendar startDT = Calendar.getInstance();
		startDT.setTime(date);
		startDT.add(Calendar.YEAR, year);
		return startDT.getTime();
	}

	/**
	 * 在指定日期上增加或减少秒数 *
	 */
	public static Date addSeconds(Date date, int seconds) {
		Calendar startDT = Calendar.getInstance();
		startDT.setTime(date);
		startDT.add(Calendar.SECOND, seconds);
		return startDT.getTime();
	}

	/**
	 * 将指定日期增加一天然后减去一毫秒
	 */
	public static Date addDayAndMinusSecond(Date date) {
		if (date == null) {
			return null;
		}
		Calendar startDT = Calendar.getInstance();
		startDT.setTime(date);
		startDT.add(Calendar.DAY_OF_MONTH, 1);
		startDT.add(Calendar.MILLISECOND, -1);
		return startDT.getTime();
	}


	/**
	 * 判断 between是否在startDate与endDate之间
	 */
	public static boolean between(Date between, Date startDate, Date endDate) {
		if (between == null || (startDate == null && endDate == null)) {
			return false;
		}
		if (startDate != null && between.getTime() < startDate.getTime()) {
			return false;
		}
		if (endDate != null && between.getTime() > endDate.getTime()) {
			return false;
		}
		return true;
	}

	/**
	 * 获取两个日期间隔天数，满24小时才算1天，结果有正负之分
	 */
	public static int getIntervalDays(Date start, Date end) {
		return (int) Math.floor((end.getTime() - start.getTime()) / (double) (MILLISECOND_OF_SECOND * SECOND_OF_MINUTE * MINUTE_OF_HOUR * HOUR_OF_DAY));
	}

	/**
	 * 获取两个时间相差天数
	 *
	 * @param start
	 * @param end
	 * @return
	 */
	public static int getIntervalDays_currt(Date start, Date end) {

		return getDays(end) - getDays(start);
	}

	public static int getDays(Date date) {
		if (date == null) {
			return -1;
		}

		return (int) (getFirstSecOfDate(date).getTime() / (1L * MILLISECOND_OF_SECOND * SECOND_OF_MINUTE * MINUTE_OF_HOUR * HOUR_OF_DAY));
	}

	/**
	 * 获取当前日期 精确到天 时间全为0时0分0秒
	 *
	 * @return
	 */
	public static Date getCurrentDate() {
		return getDate();
	}

	private static Date getDate() {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	/**
	 * 将 pattern 格式的时间字符串转换为时间
	 *
	 * @param str
	 * @param pattern
	 * @return
	 */
	public static Date strToDate(String str, String pattern) {
		if (StringUtils.isEmpty(str)) {
			return null;
		}
		if (pattern == null) {
			pattern = "yyyy-MM-dd HH:mm:ss";
		}
		SimpleDateFormat dt = new SimpleDateFormat(pattern);
		try {
			return dt.parse(str);
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * 获取一个日期是星期几
	 *
	 * @param date
	 * @return 1:星期一；2:星期二；3：星期三；4：星期四；5星期五；6：星期六；7：星期天
	 */
	public static int getDayOfWeek(Date date) {
		if (date == null) {
			return -1;
		}
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
		if (dayOfWeek == 1) {
			return 7;
		}
		return dayOfWeek - 1;
	}

	// 1 奇数, 2 偶数
	public static int isOddDay(Date date) {
		if (date == null) {
			return -1;
		}
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int num = cal.get(Calendar.DAY_OF_MONTH);
		return num % 2 == 0 ? 2 : 1;
	}

	/**
	 * 取得当前日期
	 *
	 * @return
	 */
	public static Timestamp getNow() {
		return new Timestamp(System.currentTimeMillis());
	}

	/**
	 * 比较日期 1大于  0相等  -1小于 ,d1和d2 都是null 返回0, d1==null 返回 -1, d2==null 返回 1
	 *
	 * @param d1
	 * @param d2
	 * @return
	 */
	public static int compareDate(Date d1, Date d2) {
		if (d1 == null && d2 == null) {
			return 0;
		} else if (d1 == null) {
			return -1;
		} else if (d2 == null) {
			return 1;
		}


		if (d1 == d2) {
			return 0;
		}
		if (d1.getTime() - d2.getTime() > 0) {
			return 1;
		} else if (d1.getTime() - d2.getTime() == 0) {
			return 0;
		} else {
			return -1;
		}
	}

	/**
	 * 获取当天日期的下一天日期，只有年月日
	 *
	 * @return
	 */
	public static Date getNextDate() {
		Calendar calendar = Calendar.getInstance();
		Date currentDate = getCurrentDate();
		calendar.setTime(currentDate);
		calendar.add(Calendar.DATE, 1);
		return calendar.getTime();
	}

	/**
	 * 指定日期的第一秒 如2008-08-08 00:00:00
	 *
	 * @param date
	 * @return
	 */
	public static Date getFirstSecOfDate(Date date) {
		return getDatetime(date, " 00:00:00");
	}

	private static Date getDatetime(Date date, String s) {
		DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		String formatDate = format.format(date);
		formatDate += s;
		Date result = null;
		try {
			result = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(formatDate);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * 指定日期的最后一秒 如2008-08-08 23:59:59
	 *
	 * @param date
	 * @return
	 */
	public static Date getLastSecOfDate(Date date) {
		return getDatetime(date, " 23:59:59");
	}

	/**
	 * 指定日期的下一天
	 *
	 * @param date 指定的日期
	 * @return 指定日期的下一天
	 */
	public static Date getNextOfDate(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DATE, 1);
		return calendar.getTime();
	}

	/**
	 * 查询两个时间的间隔天数      返回date1距date2已过去多少天了  ep. date1=today   date2=tomrrow  返回结果：1
	 *
	 * @param date1
	 * @param date2
	 * @return 两个时间的间隔天数
	 */
	public static int getGapDays(Date date1, Date date2) {
		date1 = getFirstSecOfDate(date1);
		date2 = getFirstSecOfDate(date2);
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date1);
		long time1 = calendar.getTimeInMillis();
		calendar.setTime(date2);
		long time2 = calendar.getTimeInMillis();
		long between_days = (time2 - time1) / (1000 * 3600 * 24);
		return Integer.parseInt(String.valueOf(between_days));
	}


	/**
	 * 取指定间隔天数的日期列表
	 *
	 * @param sDate 开始时间
	 * @param eDate 结束时间
	 * @param step  间隔天数
	 * @return
	 */
	public static List<Date> queryEveryday(Date sDate, Date eDate, int step) {
		step = step <= 0 ? 1 : step;
		Date startDate = getFirstSecOfDate(sDate);
		Date endDate = getLastSecOfDate(eDate);
		int dayPoint = (getGapDays(startDate, endDate) + 1) / step;
		List<Date> result = new ArrayList<Date>(dayPoint);
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(startDate);
		do {
			result.add(calendar.getTime());
			calendar.add(Calendar.DATE, step);
		} while (compareDate(endDate, calendar.getTime()) >= 0);
		return result;
	}

	/**
	 * 取指定日期内的间隔几周的指定星期日期
	 *
	 * @param sDate      开始日期
	 * @param eDate      结束日期
	 * @param dateOfWeek 星期几
	 * @param gapWeek    间隔的周数
	 * @return
	 */
	public static List<Date> queryDayOfWeek(Date sDate, Date eDate, int dateOfWeek, int gapWeek) {
		gapWeek = gapWeek <= 0 ? 1 : gapWeek;
		Date startDate = getFirstSecOfDate(sDate);
		Date endDate = getLastSecOfDate(eDate);
		Calendar endCalendar = Calendar.getInstance();
		endCalendar.setTime(endDate);
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(startDate);
		List<Date> result = new ArrayList<Date>();
		do {
			calendar.set(Calendar.DAY_OF_WEEK, dateOfWeek);
			result.add(calendar.getTime());
			calendar.add(Calendar.DATE, 7 * gapWeek);
		} while (compareDate(calendar.getTime(), endDate) <= 0
				|| calendar.get(Calendar.WEEK_OF_YEAR) <= endCalendar.get(Calendar.WEEK_OF_YEAR));
		return result;
	}

	/**
	 * 返回指定日期在一周中的指定星期几的日期
	 *
	 * @param date
	 * @param dateOfWeek
	 * @return
	 */
	public static Date getDayOfWeek(Date date, int dateOfWeek) {
		date = getFirstSecOfDate(date);
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.DAY_OF_WEEK, dateOfWeek);
		return calendar.getTime();
	}

	/**
	 * 返回指定日期内指定间隔个月的每月的号数日期
	 *
	 * @param sDate    开始日期
	 * @param eDate    结束日期
	 * @param whichDay 指定的号数
	 * @param gapMonth 间隔的个月数
	 * @return
	 */
	public static List<Date> queryDayOfMonth(Date sDate, Date eDate, int whichDay, int gapMonth) {
		gapMonth = gapMonth <= 0 ? 1 : gapMonth;
		Date startDate = getDayOfMonth(sDate, whichDay);
		Date endDate = getDayOfMonth(eDate, whichDay);
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(startDate);
		List<Date> result = new ArrayList<Date>();
		do {
			result.add(getDayOfMonth(calendar.getTime(), whichDay));
			calendar.add(Calendar.MONTH, gapMonth);
		} while (compareDate(calendar.getTime(), endDate) <= 0);
		return result;
	}

	/**
	 * 取日期所在的那个月的多少号
	 *
	 * @param date     指定的日期
	 * @param whichDay 指定的号数
	 * @return
	 */
	public static Date getDayOfMonth(Date date, int whichDay) {
		if (whichDay < 1) {
			whichDay = 1;
		}
		if (whichDay > 28) {
			whichDay = 28;
		}
		String dayOfMonth;
		if (whichDay < 10) {
			dayOfMonth = "-0" + whichDay;
		} else {
			dayOfMonth = "-" + whichDay;
		}
		try {
			return new SimpleDateFormat("yyyy-MM-dd").parse(formatDate(date, "yyyy-MM") + dayOfMonth);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return date;
	}

	/**
	 * 取指定日期内指定年限间隔的每年的第一天
	 * e.g.传入 2015-09-01,2017-05-02,1则返回2015-01-01、2016-01-01、2017-01-01
	 *
	 * @param sDate
	 * @param eDate
	 * @param gapYear
	 * @return
	 */
	public static List<Date> queryFirstDayOfYear(Date sDate, Date eDate, int gapYear) {
		Date startDate = getFirstDayOfYear(sDate);
		Date endDate = getFirstDayOfYear(eDate);
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(getFirstDayOfYear(startDate));
		List<Date> result = new ArrayList<Date>();
		do {
			result.add(calendar.getTime());
			calendar.add(Calendar.YEAR, gapYear);
		} while (compareDate(endDate, calendar.getTime()) >= 0);
		return result;
	}

	/**
	 * 返回指定日期所在年的第一天
	 * e.g.input:2015-06-01,output:2015-01-01
	 *
	 * @param date
	 * @return
	 */
	public static Date getFirstDayOfYear(Date date) {
		try {
			return new SimpleDateFormat("yyyy-MM-dd").parse(formatDate(date, "yyyy") + "-01-01");
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 返回指定日期所在年的最后一天
	 * e.g.input:2015-06-01,output:2015-01-01
	 *
	 * @param date
	 * @return
	 */
	public static Date getEndDayOfYear(Date date) {
		try {
			return new SimpleDateFormat("yyyy-MM-dd").parse(formatDate(date, "yyyy") + "-12-31");
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 获取当前日期 精确到月
	 *
	 * @return
	 */
	public static String getCurrenctDateMoth(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.YEAR) + "-" + (calendar.get(Calendar.MONTH) + 1);
	}

	/**
	 * @param date     指定日期
	 * @param whichDay 那一号
	 * @return
	 * @Description 取日期所在的月的多少号
	 * @author owen.he
	 * @date 2016年1月29日 下午5:01:47
	 */
	public static Date getDayOfCurrentMonth(Date date, int whichDay) {
		if (whichDay < 1) {
			whichDay = 1;
		}
		if (whichDay > 31) {
			whichDay = 30;
		}
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.DATE, whichDay);
		return calendar.getTime();
	}

	/**
	 * 两个日期间隔的个月数
	 *
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static int getMonthSpace(Date date1, Date date2) {
		if (date1 == null || date2 == null) {
			return -1;
		}
		Calendar calendar1 = Calendar.getInstance();
		Calendar calendar2 = Calendar.getInstance();
		calendar1.setTime(date1);
		calendar2.setTime(date2);
		int year1 = calendar1.get(Calendar.YEAR);
		int year2 = calendar2.get(Calendar.YEAR);
		int month1 = calendar1.get(Calendar.MONTH);
		int month2 = calendar2.get(Calendar.MONTH);
		return (year1 - year2) * 12 + month1 - month2;
	}

	/**
	 * 获取当前时间
	 *
	 * @return
	 */
	public static String refFormatNowDate() {
		Date nowTime = new Date(System.currentTimeMillis());
		SimpleDateFormat sdFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String retStrFormatNowDate = sdFormatter.format(nowTime);
		return retStrFormatNowDate;
	}

	/**
	 * 获取两个日期间隔秒数
	 */
	public static int getIntervalSecond(String dateStringStart, String dateStringEnd) throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date start = sdf.parse(dateStringStart);
		Date end = sdf.parse(dateStringEnd);
		return (int) Math.floor((end.getTime() - start.getTime()) / (double) MILLISECOND_OF_SECOND);
	}

	/**
	 * 获取精确到秒的时间戳
	 *
	 * @return
	 */
	public static int getSecondTimestamp(Date date) {
		if (null == date) {
			return 0;
		}
		String timestamp = String.valueOf(date.getTime());
		int length = timestamp.length();
		if (length > 3) {
			return Integer.valueOf(timestamp.substring(0, length - 3));
		} else {
			return 0;
		}
	}

	/**
	 * @param date 当前时间
	 * @return
	 * @flag 0 返回yyyy-MM-dd 00:00:00日期<br>
	 * 1 返回yyyy-MM-dd 23:59:59日期
	 */
	public static Date weeHours(Date date, int flag) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int hour = cal.get(Calendar.HOUR_OF_DAY);
		int minute = cal.get(Calendar.MINUTE);
		int second = cal.get(Calendar.SECOND);
		//时分秒（毫秒数）
		long millisecond = hour * 60 * 60 * 1000 + minute * 60 * 1000 + second * 1000;
		//凌晨00:00:00
		cal.setTimeInMillis(cal.getTimeInMillis() - millisecond);

		if (flag == 0) {
			return cal.getTime();
		} else if (flag == 1) {
			//凌晨23:59:59
			cal.setTimeInMillis(cal.getTimeInMillis() + 23 * 60 * 60 * 1000 + 59 * 60 * 1000 + 59 * 1000);
		}
		return cal.getTime();
	}

	/**
	 * 获取某天的开始时间
	 *
	 * @param date
	 * @return
	 */
	public static Date getDayBeginTime(Date date) {

		Calendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}


	/**
	 * 获取某天的结束时间
	 *
	 * @param date
	 * @return
	 */
	public static Date getDayEndTime(Date date) {
		Calendar c = new GregorianCalendar();
		c.setTime(date);
		c.set(Calendar.HOUR_OF_DAY, 23);
		c.set(Calendar.MINUTE, 59);
		c.set(Calendar.SECOND, 59);
		c.set(Calendar.MILLISECOND, 999);
		return c.getTime();
	}

	/**
	 * 获取某个时间的月的第一天
	 *
	 * @param date
	 * @return
	 */
	public static Date getMonthBeginTime(Date date) {

		Calendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.set(Calendar.HOUR, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	/**
	 * 获取某个时间的月的最后一天
	 *
	 * @param date
	 * @return
	 */
	public static Date getMonthEndTime(Date date) {

		Calendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
		calendar.set(Calendar.HOUR, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		calendar.set(Calendar.MILLISECOND, 999);
		return calendar.getTime();
	}

	public static long getCurrentTimeStamp() {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date());
		return calendar.getTimeInMillis();
	}

	public static Date getFirstDayOfMonth(Date date) {
		DateFormat format = new SimpleDateFormat("yyyy-MM");
		String formatDate = format.format(date);
		formatDate = formatDate + "-01 00:00:00";
		Date result = null;

		try {
			result = (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).parse(formatDate);
		} catch (ParseException var5) {
			var5.printStackTrace();
		}
		return result;
	}

	/**
	 * 获取指定日期当月最后一天
	 *
	 * @param date
	 * @return
	 */
	public static Date getEndDayOfMonth(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), 1);
		int day = calendar.getActualMaximum(5);
		calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), day);
		return getDayEndTime(calendar.getTime());
	}

	public static Date getFirstDayOfWeek(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int i = cal.get(Calendar.DAY_OF_WEEK);
		System.out.println(i);
		if (i == 1) {
			i = 8;
		}
		return addDay(date, -1 * (i - 2));
	}

	/**
	 * 获取指定日期本周最后一天
	 *
	 * @param date
	 * @return
	 */
	public static Date getEndDayOfWeek(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int i = cal.get(Calendar.DAY_OF_WEEK);
		System.out.println(i);
		if (i == 1) {
			i = 8;
		}
		return addDay(date, -1 * (2 - i));
	}


	public static Date addMinuteToDate(Date date, int minute) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.MINUTE, minute);
		return calendar.getTime();
	}


	/**
	 * date2比date1多的天数
	 *
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static int differentDays(Date date1, Date date2) {
		Calendar cal1 = Calendar.getInstance();
		cal1.setTime(date1);

		Calendar cal2 = Calendar.getInstance();
		cal2.setTime(date2);
		int day1 = cal1.get(Calendar.DAY_OF_YEAR);
		int day2 = cal2.get(Calendar.DAY_OF_YEAR);

		int year1 = cal1.get(Calendar.YEAR);
		int year2 = cal2.get(Calendar.YEAR);
		if (year1 != year2)   //同一年
		{
			int timeDistance = 0;
			for (int i = year1; i < year2; i++) {
				if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0)    //闰年
				{
					timeDistance += 366;
				} else    //不是闰年
				{
					timeDistance += 365;
				}
			}

			return timeDistance + (day2 - day1);
		} else    //不同年
		{
			System.out.println("判断day2 - day1 : " + (day2 - day1));
			return day2 - day1;
		}
	}

	/**
	 * 计算时间（昨天、今天、X-X-X）
	 */
	public static String turnTimeToDate(Date time) {
		if (formatDate(addDay(new Date(), -1), DT_SHORT).equals(formatDate(time, DT_SHORT))) {
			return "昨天";
		} else if (formatDate(new Date(), DT_SHORT).equals(formatDate(time, DT_SHORT))) {
			return formatDate(time, "HH:mm");
		} else {
			return formatDate(time, "yyyy-MM-dd");
		}
	}

	/**
	 * 获取本月大小月
	 * @param date
	 * @return 1.大月 0.小月 -1.2月
	 */
	public static int monthSize(Date date) {
		Date date1 = getMonthEndTime(date);
		Integer lastDay = Integer.valueOf(formatDate(date1, "dd"));
		return lastDay < 30 ? -1 : (lastDay > 30 ? 1 : 0);
	}

	/**
	 * 将日期转换为cron表达式
	 *
	 * @param date
	 * @return
	 */
	public static String getCronExpression(Date date) {
		String[] cronArr = new String[7];
		for (int i = 0; i < cronArr.length; i++) {
			cronArr[i] = "";
		}
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		int second = calendar.get(Calendar.SECOND);
		int minute = calendar.get(Calendar.MINUTE);
		int hour = calendar.get(Calendar.HOUR_OF_DAY);
		int day = calendar.get(Calendar.DAY_OF_MONTH);
		int month = calendar.get(Calendar.MONTH) + 1;
		int year = calendar.get(Calendar.YEAR);

		cronArr[0] = second + "";
		cronArr[1] = minute + "";
		cronArr[2] = hour + "";

		cronArr[3] = day + "";
		cronArr[4] = month + "";
		cronArr[5] = "?";
		cronArr[6] = year + "";

		String cron = StringUtils.join(cronArr, " ").trim();
		return cron;
	}

	/**
	 * 将时间戳转换为cron表达式
	 *
	 * @param timeStamp
	 * @return
	 */
	public static String getCronExpression(String timeStamp) {
		return getCronExpression(new Date(new Long(timeStamp)));
	}

	public static void main(String[] args) {
//		System.out.println(parseDate("2018-05-14 16:20:01"));
		// Thu May 18 2017 00:00:00 GMT+0800
		System.out.println(parseGMTTime("Thu May 18 2017 00:00:00 GMT+0800"));
////
////		String strDate = "2018-05-14 16:20:01";
////
////		Date date = new Date();
////
//////		System.out.println(strDate + " 今天是哪一年？" + getYear(date));
//////		System.out.println(strDate + " 今天是哪个月？" + getMonth(date));
//////		System.out.println(strDate + " 今天是几号？" + getDay(date));
////
////		System.out.println(strDate + " 当月第一天日期？"
////				+ formatDate(getFirstDateOfMonth(date)));
////		System.out.println(strDate + " 当月最后一天日期？"
////				+ formatDate(getLastDateOfMonth(date)));
////
////		System.out.println(strDate + " 所在周期第一天日期？"
////				+ formatDate(getFirstDateOfSeason(date)));
////		System.out.println(strDate + " 所在周期最后一天日期？"
////				+ formatDate(getLastDateOfSeason(date)));
////		int i = getSeason(date)-1;
////		System.out.println(strDate + " 上一个周期" + formatDate(getBeforeOfDate(date)));
////		System.out.println(strDate + " 所在季度月份？"
////				+ formatDate(getSeasonDate(date)[0], "yyyy年MM月") + "/"
////				+ formatDate(getSeasonDate(date)[1], "yyyy年MM月") );
//
//		Date today = getDateOfToday();
//		System.out.println(formatDate(today, yyyyMMddHHmmss));
//
//		Date d = addDate(getDateOfToday(), 20);
//		System.out.println(formatDate(d, yyyyMMddHHmmss));
	}

	public static Date getLastDayOfWeek(Date date) {
		Calendar cal = Calendar.getInstance();
		try {
			cal.setTime(date);
			cal.set(Calendar.DAY_OF_WEEK, 1);
			cal.set(Calendar.DATE, cal.get(Calendar.DATE) + 6);
		} catch(Exception e) {
			e.printStackTrace();
		}
		return cal.getTime();
	}

	/**
	 * 获取当前时间的小时
	 * @return 小时
	 */
	public static int getHour() {
		return LocalDateTime.now().getHour();
	}
	public static LocalDate dateToLocaleDate(Date date) {

		Instant  instant = date.toInstant();

		ZoneId zoneId  = ZoneId.systemDefault();

		return instant.atZone(zoneId).toLocalDate();

	}

}